home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 September / Macworld (1998-09).dmg / Shareware World / Info / For Developers / MacZoop 1.8.3 / More Classes / File Classes / ZBlockFile.h < prev    next >
Text File  |  1997-03-05  |  5KB  |  162 lines

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp        -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZBlockFile.h        -- a generic file object that includes some basic block
  9. *                                    management facilities. This type of file is useful for
  10. *                                    implementing VM schemes and databases, etc.
  11. *
  12. *
  13. *            © 1996, Graham Cox
  14. *
  15. *
  16. *
  17. *
  18. *************************************************************************************************/
  19.  
  20. #pragma once
  21.  
  22. #ifndef __ZBLOCKFILE__
  23. #define __ZBLOCKFILE__
  24.  
  25.  
  26. #include    "ZFile.h"
  27.  
  28.  
  29. class    ZArray;
  30.  
  31.  
  32. class    ZBlockFile    : public ZFile
  33. {
  34. protected:
  35.     ZArray*        bmap;
  36.     long        refSeed;
  37.     long        useCount;
  38.     
  39. public:
  40.     ZBlockFile( const FSSpec& aFileSpec );
  41.     ZBlockFile( Str255 fName );
  42.     ~ZBlockFile();
  43.     
  44. // overrides:
  45.  
  46.     virtual void            Open();
  47.     virtual void            Close();
  48.     
  49. // specific to this class:
  50.     
  51.     virtual long            AddBlock();
  52.     virtual void            AddBlockUsingRef( const long aRef );
  53.     virtual void            RemoveBlock( const long ref );
  54.  
  55.     virtual void            GetBlockData( const long ref, void* dataPtr, long* dataLen );
  56.     virtual void            GetBlockData( const long ref, Handle dataH );
  57.     
  58.     virtual void            SetBlockData( const long ref, void* dataPtr, long dataLen );
  59.     virtual void            SetBlockData( const long ref, Handle dataH );
  60.     
  61.     virtual long            GetNewRefSeed() { return ++refSeed; };
  62.     virtual long            GetBlockCount();
  63.     virtual long            GetBlock( const long ref );
  64.     virtual long            GetBlockRef( const long bkIndex );
  65.     virtual unsigned long    GetBlockSize( const long bkIndex );
  66.  
  67. protected:
  68.     
  69.     virtual void            AppendBlock( const long ref, const unsigned long sizeNeeded );
  70.     virtual long            FindFreeBlock( const unsigned long sizeNeeded );
  71.     virtual void            FreeBlock( const long bkIndex );
  72.     virtual void            SplitBlock( const long bkIndex, const unsigned long bkSize );
  73.     virtual void            ReallocBlock( const long ref, long newBkSize );
  74.     virtual void            SetMarkToBlock( const long bkIndex );
  75.     
  76.     virtual void            ReadMap() {};
  77.     virtual void            WriteMap() {};
  78.     virtual void            InitMap();
  79.     virtual void            WriteHeader() {};
  80.     
  81.     virtual void            CompactMap();
  82.     virtual void            CompactFile() {};
  83. };
  84.  
  85. // we force 68k alignment for when the map is stored in the file- the file will work
  86. // on either platform.
  87.  
  88. #if PRAGMA_ALIGN_SUPPORTED
  89. #pragma options align=mac68k
  90. #endif
  91.  
  92. // block status:
  93.  
  94. typedef enum
  95. {
  96.     free,
  97.     notFree
  98. }
  99. BlockStatus;
  100.  
  101.  
  102. // this is what is stored in the <bmap> array, one for every block in the file:
  103.  
  104. typedef struct
  105. {
  106.     long            fRefNum;
  107.     unsigned long    fMark;
  108.     unsigned long    fSize;
  109.     BlockStatus        fStatus;
  110. }
  111. Block;
  112.  
  113. #if PRAGMA_ALIGN_SUPPORTED
  114. #pragma options align=reset
  115. #endif
  116.  
  117. // possible errors:
  118.  
  119. enum
  120. {
  121.     kBlockFileNotOpenErr    = 257,
  122.     kBlockBadRefErr,
  123.     kBlockNotFoundErr,
  124.     kBlockDupRefErr,
  125.     kBadSplitReqErr
  126. };
  127.  
  128. /*
  129.  
  130. This object is a file which is subdivided into a sequence of multiple blocks. This is useful
  131. when you want to store in a single file a lot of different things. Each item in the file must
  132. have a unique "block reference number", which can be allocated sequentially from a seed if
  133. you desire. Otherwise, for temporary files, you could use an object address- as long as the
  134. value is unique it doesn't matter. You can then get and set the block's data at any time- this
  135. object looks after where it is stored in the file. Before you can do this, you must register
  136. the block refnum using AddBlock(). This creates an entry in the map table referring to this
  137. block. If you no longer need the block, calling RemoveBlock() will free the space in the file
  138. for other's use.
  139.  
  140. If you want to use this class for permanent files, the map itself must be saved in the file
  141. and recovered when it is opened. To do this, you must override WriteHeader, WriteMap and
  142. ReadMap. The header should generally include an offset to the start of the map so that you can
  143. read it back into memory.
  144.  
  145. The methods in this object manage the filespace reasonably efficiently, but never split data
  146. into non-contiguous segments. Thus the file will grow but not automatically shrink (though
  147. freed space is always re-used where possible for new data). To shrink the file, you can call
  148. CompactFile(), which will remove all unused space. This may take a while due to the amount of
  149. data movement needed on disk, and uses a progress bar. CompactMap() is a much faster operation
  150. which conjoins all adjacent free blocks into larger ones, thus making the reuse of such parts
  151. of the file much more likely. This is called internally and you shouldn't need to call it
  152. yourself.
  153.  
  154. This object makes no assumptions whatever about the data you store- as long as you supply its
  155. total size in bytes, it will store and return it to you. You are free to change the size once
  156. the block is written- the position within the file where the data is saved is automatically
  157. managed so that you can always retrieve it and that freed space becomes available for new data.
  158.  
  159. */
  160.  
  161.  
  162. #endif